package com.xingfly.event.component;

import com.xingfly.event.EventRecord;
import com.xingfly.event.EventRecordRepository;
import com.xingfly.event.shared.model.DomainEvent;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Optional;

/**
 * Created by SuperS on 2019/11/22.
 *
 * @author SuperS
 */
@Component
public class DomainEventConsumeWrapper {

    private EventRecordRepository eventRecordRepository;

    public DomainEventConsumeWrapper(EventRecordRepository eventRecordRepository) {
        this.eventRecordRepository = eventRecordRepository;
    }

    @Transactional(rollbackFor = Exception.class)
    public Object recordAndConsume(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        Optional<Object> optionalEvent = Arrays.stream(args)
                .filter(o -> o instanceof DomainEvent)
                .findFirst();
        if (!optionalEvent.isPresent()) {
            return joinPoint.proceed();
        }
        DomainEvent event = (DomainEvent) optionalEvent.get();
        EventRecord record = eventRecordRepository.findEventRecordById(event.getEventId());
        if (record != null) {
            return null;
        }
        EventRecord newRecord = new EventRecord();
        newRecord.setId(event.getEventId());
        eventRecordRepository.save(newRecord);
        return joinPoint.proceed();
    }
}
